package com.mlx.meng.aop;

import com.mlx.meng.annotation.DataPermissionRow;
import com.mlx.meng.author.AbstractDataPermissionRowAuthorization;
import com.mlx.meng.tool.DataPermissionException;
import com.mlx.meng.verify.DataPermissionRowVerification;
import com.mlx.meng.tool.DataPermissionUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

@Aspect
@Order(20000)
public class DataPermissionRowAOP {

    @Autowired(required = false)
    private AbstractDataPermissionRowAuthorization<?> authorization;

    @Pointcut(value = "@annotation(com.mlx.meng.annotation.DataPermissionRow)")
    public void dataFilterPointcut(){
    }

    private DataPermissionRow getDataAuthorAnnotation(JoinPoint joinPoint){
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        return method.getDeclaredAnnotation(DataPermissionRow.class);
    }

    @AfterReturning(value = "dataFilterPointcut()", returning = "dataList")
    public void dataFilter(JoinPoint joinPoint, Object dataList) throws Exception{

        long startTime = System.currentTimeMillis();

        if (dataList == null){
            return;
        }
        if (!(dataList instanceof Collection)){
            return;
        }
        if (((Collection<?>) dataList).isEmpty()){
            return;
        }

        // 获取数据授权注解
        DataPermissionRow dataPermissionAnnotation = getDataAuthorAnnotation(joinPoint);
        // 获取表名属性
        String tableName = dataPermissionAnnotation.tableName();
        // 获取外键映射属表达式数组
        String[] foreignKeys = dataPermissionAnnotation.foreignKeys();
        // 获取启动状态
        boolean disEnable = dataPermissionAnnotation.disEnable();
        // 获取获取方法名称
        String getMethodName = dataPermissionAnnotation.getMethodName();

        Class<?> methodParamType = dataPermissionAnnotation.getMethodParamType();
        // 如果不是启动状态，不进行行数据权限过滤
        if (disEnable){
            return;
        }



        // 如果getMethodName为空，根据权限字段名称获取对应属性的属性值进行权限判断；
        // 否则获取getMethodName指定的方法，通过权限字段名称为方法参数获取对应权限字段的值进行权限判断
        if (DataPermissionUtil.isEmpty(getMethodName)){
            authorization.dataFilter((Collection<?>) dataList, tableName, foreignKeys);
        }else {
            authorization.dataFilter((Collection<?>) dataList, tableName, foreignKeys, getMethodName, methodParamType);
        }

        long endTime = System.currentTimeMillis();

        System.out.println(String.format("列数据权限过滤执行时间：【%d】ms", endTime - startTime));
    }


//    @AfterReturning(value = "dataFilterPointcut()", returning = "dataList")
//    public void dataFilter(JoinPoint joinPoint, Object dataList) throws Exception{
//
//        long startTime = System.currentTimeMillis();
//
//        if (dataList == null){
//            return;
//        }
//        if (!(dataList instanceof Collection)){
//            return;
//        }
//        if (((Collection<?>) dataList).isEmpty()){
//            return;
//        }
//
//        // 获取数据授权注解
//        DataPermissionRow dataPermissionAnnotation = getDataAuthorAnnotation(joinPoint);
//        // 获取表名属性
//        String tableName = dataPermissionAnnotation.tableName();
//        // 获取外键映射属表达式数组
//        String[] foreignKeys = dataPermissionAnnotation.foreignKeys();
//        // 获取启动状态
//        boolean disEnable = dataPermissionAnnotation.disEnable();
//        // 获取获取方法名称
//        String getMethodName = dataPermissionAnnotation.getMethodName();
//
//        Class<?> methodParamType = dataPermissionAnnotation.getMethodParamType();
//        // 如果不是启动状态，不进行行数据权限过滤
//        if (disEnable){
//            return;
//        }
//
//        // 获取用户所有的行数据权限
//        DataPermissionRowVerification rowPermission = authorization.getDataPermissionRow();
//        // 通过表名、外键映射表达式数组构建用户对于指定表的行数据权限
//        DataPermissionRowVerification.DataPermissionRowEntityVerification entityVerification = rowPermission.buildEntityDataPermissionRow(tableName, foreignKeys);
//
//        // 如果没有行数据权限，清空所有数据
//        if (entityVerification.isNotExistDataPermission()){
//            ((Collection<?>) dataList).clear();
//            return;
//        }
//
//        // 获取数据类型
//        Iterator<?> iterator1 = ((Collection<?>) dataList).iterator();
//        Object next = iterator1.next();
//        Class<?> aClass = next.getClass();
//
//        // 生成迭代器
//        Iterator<?> iterator = ((Collection<?>) dataList).iterator();
//
//        // 如果getMethodName为空，根据权限字段名称获取对应属性的属性值进行权限判断；
//        // 否则获取getMethodName指定的方法，通过权限字段名称为方法参数获取对应权限字段的值进行权限判断
//        if (DataPermissionUtil.isEmpty(getMethodName)){
//            // 获取数据类型的属性集合
//            Map<String, Field> fieldMap = DataPermissionUtil.gainClassField(aClass);
//            // 获取所有的权限字段
//            Set<String> permissionField = entityVerification.getPermissionField();
//            // 检查数据类型是否拥有对应权限字段的属性
//            for (String k : permissionField){
//                if (!(fieldMap.containsKey(k))){
//                    throw new DataPermissionException("返回数据的数据类型不存在权限字段【%s】指定的属性", k);
//                }
//            }
//
//            // 行数据权限过滤
//            while (iterator.hasNext()){
//                // 获取集合中的元素
//                Object data = iterator.next();
//                // 通过集合中的元素与属性集合判断是否拥有对应数据权限
//                if (entityVerification.isNotDataPermission(data, fieldMap)){
//                    // 没有数据权限被过滤掉
//                    iterator.remove();
//                }
//            }
//        }else {
//            // 获取getMethodName指定的属性值获取方法
//            Method method = aClass.getDeclaredMethod(getMethodName, methodParamType);
//            // 行数据权限过滤
//            while (iterator.hasNext()){
//                // 获取集合中的元素
//                Object data = iterator.next();
//                // 通过集合中的元素与与属性值获取方法判断是否拥有对应数据权限
//                if (entityVerification.isNotDataPermission(data, method)){
//                    // 没有数据权限被过滤掉
//                    iterator.remove();
//                }
//            }
//        }
//
//        long endTime = System.currentTimeMillis();
//
//        System.out.println(String.format("列数据权限过滤执行时间：【%d】ms", endTime - startTime));
//    }
}
